﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace Windows8Accelerator.Core.Xaml.Storage
{
    //TODO: Compat

    public class StorageHelper : StorageHelperBase
    {
        private static IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication();

        public static IsolatedStorageFileStream OpenLocalFile(string name)
        {
            if (!ISF.FileExists(name))
                return null;
            return ISF.OpenFile(name, FileMode.Open, FileAccess.Read);
        }

        public static async Task<string> GetStorageFolderAsync(string name, StorageLocation location)
        {
            if (name == null)
                name = "";
            name = name.Replace('/', '\\');
            if (!string.IsNullOrEmpty(Path.GetDirectoryName(name)))
                name = Path.GetDirectoryName(name);

            string folder = null;
            switch (location)
            {
                case StorageLocation.Local:
                    folder = Path.Combine("Local", name);
                    break;
                case StorageLocation.Roaming:
                    folder = Path.Combine("Roaming", name);
                    break;
                case StorageLocation.Temp:
                    folder = Path.Combine("Temp", name);
                    break;
                case StorageLocation.InstalledLocation:
                    folder = Path.Combine("InstalledLocation", name);
                    break;
                case StorageLocation.Path:
                    folder = name;
                    break;
            }

            if (name != null && location != StorageLocation.Path && location != StorageLocation.InstalledLocation)
            {
                if (!ISF.DirectoryExists(folder))
                    ISF.CreateDirectory(folder);

                //var folderNames = Path.GetDirectoryName(name).Split(new char[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries);
                //foreach (var folderName in folderNames)
                //{
                //    ISF.CreateDirectory(folderName);
                //}
            }

            return folder;
        }

        public override async Task<FileInfo[]> GetFilesAsync(string directory, StorageLocation storageLocation)
        {
            var folder = await GetStorageFolderAsync(directory, storageLocation);            
            var files = ISF.GetFileNames(Path.Combine(folder,"*"));
            return files.Select(
                (f) => new FileInfo()
                {
                    Path = Path.Combine(folder, f),
                    Name = Path.GetFileName(f),
                    DateCreated = ISF.GetCreationTime(f),
                }
                ).ToArray();
        }

        public override async Task DeleteFilesAsync(string filePath, StorageLocation location)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            var file = Path.Combine(folder, Path.GetFileName(filePath));
            ISF.DeleteFile(file);
        }

        public override async Task CreateFileAsync(string filePath, StorageLocation location)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            var file = Path.Combine(folder, Path.GetFileName(filePath));
            if (ISF.FileExists(file))
                ISF.DeleteFile(file);
            ISF.CreateFile(file);
        }

        public override async Task<Stream> OpenFileWriteAsync(string filePath, StorageLocation location, bool createIfNecessary = false)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            var file = Path.Combine(folder, Path.GetFileName(filePath));

            if (!ISF.FileExists(file) && createIfNecessary)
                ISF.CreateFile(file);
            else 
                throw new FileNotFoundException(filePath);
            
            return ISF.OpenFile(file, FileMode.Open, FileAccess.ReadWrite);
        }

        public override async Task<Stream> OpenFileReadAsync(string filePath, StorageLocation location)
        {
            var folder = await GetStorageFolderAsync(filePath, location);
            var file = Path.Combine(folder, Path.GetFileName(filePath));

            if (file.StartsWith("InstalledLocation"))
            {
                file = file.Substring("InstalledLocation\\".Length);
                var resource = Application.GetResourceStream(new Uri(file, UriKind.Relative));
                return resource.Stream;
            }

            if (!ISF.FileExists(file))
                throw new FileNotFoundException(filePath);

            return ISF.OpenFile(file, FileMode.Open, FileAccess.Read);
        }
    }
}
